import datetime
import json
import random
from audioop import reverse

from decimal import Decimal
from django import http
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator


from django.shortcuts import render, redirect
from django.utils import timezone
from django.views import View
# Create your views here.


# from fdfs_client.client import Fdfs_client
# client = Fdfs_client('utils/fastdfs/client.conf')
# client.upload_by_filename('/home/python/Desktope/64e480cd17fe5546a32b6754afb6de.jpg')
from django_redis import get_redis_connection


from apps.contents.utils import get_categories
from apps.goods import models
from apps.goods.models import GoodsCategory, SKU, GoodsVisitCount
from apps.goods.utils import get_breadcrumb
from apps.order.models import OrderInfo, OrderGoods
from utils.response_code import RETCODE
from utils.views import LoginRequiredJSONMixin


class ListView(View):
    """商品列表页"""

    def get(self, request,cat_id,page_num):
        """提供商品列表页"""
        '''
        1.根据分类id获取数据
        2.根据分类信息组织面包屑
        3.根据分类id获取商品所有数据
        '''
        try:
            category = GoodsCategory.objects.get(id=cat_id)

        except Exception:
            return render(request, '404.html')

        # 接受sort参数,如果用户不传,就是默认的排序规则
        sort = request.GET.get('sort','default')


        # 查询商品分类
        # category = get_categories()
        # 查询面包屑
        breadcrumb = get_breadcrumb(category)

        # 按照价格升序排序
        if sort == 'prices':
            sort_field = 'prices'
        # 按照销量升序排序
        elif sort == 'sales':
            sort_field = '-sales'
        # 按照默认排序   默认排序按照上架时间
        else:
            sort_field = '-create_time'

        # 进行排序
        skus = SKU.objects.filter(category=category).order_by(sort_field)

        # 创建分页类实例
        paginator = Paginator(object_list=skus,per_page=5)
        # 获取指定页数
        page = paginator.page(page_num)

        # 获取总页数
        total_page = paginator.num_pages


        # 渲染页面
        context = {
            'breadcrumb': breadcrumb,
            'sort': sort,  # 排序字段
            'category': category,  # 第三级分类
            'page': page,  # 分页后数据
            'total_page': total_page,  # 总页数
            'page_num': page_num,  # 当前页码
        }
        return render(request, 'list.html', context)

    '''
    热销数据根据ajax来获取
    '''


class HotGoodsView(View):
    """商品热销排行"""

    def get(self, request, cat_id):
        """提供商品热销排行JSON数据"""
        # 根据销量倒序
        try:
            categories = GoodsCategory.objects.get(id=cat_id)
        except Exception:
            return http.JsonResponse({'code': RETCODE.NODATAERR, 'errmsg': '暂无此分类'})
        # 根据销量倒序  获取前两个
        skus = SKU.objects.filter(category=categories).order_by('-sales')[:2]

        # 序列化
        hot_skus = []
        for sku in skus:
            hot_skus.append({
                'id':sku.id,
                'default_image_url':sku.default_image.url,
                'name':sku.name,
                'price':sku.price,
            })

        return http.JsonResponse({'code':RETCODE.OK, 'errmsg':'OK', 'hot_skus':hot_skus})




from django import http
from django.shortcuts import render
from django.views import View
from apps.contents.utils import get_categories
from apps.goods.models import SKU, GoodsCategory
from apps.goods.utils import get_breadcrumb
from utils.response_code import RETCODE


class DetailView(View):

    def get(self,request,sku_id):

        # 获取当前sku的信息
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return render(request, '404.html')

        # 查询商品频道分类
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(sku.category)

        # 构建当前商品的规格键
        sku_specs = sku.specs.order_by('spec_id')
        sku_key = []
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()
        # 构建不同规格参数（选项）的sku字典
        spec_sku_map = {}
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('spec_id')
            # 用于形成规格参数-sku字典的键
            key = []
            for spec in s_specs:
                key.append(spec.option.id)
            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id
        # 获取当前商品的规格信息
        goods_specs = sku.spu.specs.order_by('id')
        # 若当前sku的规格信息不完整，则不再继续
        if len(sku_key) < len(goods_specs):
            return
        for index, spec in enumerate(goods_specs):
            # 复制当前sku的规格键
            key = sku_key[:]
            # 该规格的选项
            spec_options = spec.options.all()
            for option in spec_options:
                # 在规格参数sku字典中查找符合当前规格的sku
                key[index] = option.id
                option.sku_id = spec_sku_map.get(tuple(key))
            spec.spec_options = spec_options

        # 渲染页面
        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'sku': sku,
            'specs': goods_specs,
        }

        return render(request,'detail.html',context)





class DetailVisitView(View):
    """详情页分类商品访问量"""

    def post(self, request, category_id):
        """记录分类商品访问量"""
        try:
            category = GoodsCategory.objects.get(id=category_id)

        except GoodsCategory.DoesNotExist:
            return http.JsonResponse({'code': RETCODE.NODATAERR, 'errmsg': '没有此分类'})
        # 获取今天的日期  和当天的分类


        today = timezone.localtime()
        try:
            gvc = GoodsVisitCount.objects.get(category=category,
                                            date=today)
        except GoodsVisitCount.DoesNotExist:

            # 查询今天该类别的商品没有访问量  则创建一个记录,然后数据加一
            GoodsVisitCount.objects.create(category=category,
                                           date=today,
                                           count=1)

        else:
            # 如果该类别的商品在今天有过访问记录，访问记录加一

            gvc.count += 1
            gvc.save()

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})


# 浏览记录
class UserBrowseHistory(LoginRequiredJSONMixin, View):
    """用户浏览记录"""

    def post(self, request):
        """保存用户浏览记录"""
        # 接收参数
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')

        # 校验参数
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.JsonResponse({'code': RETCODE.NODATAERR, 'errmsg': 'no data'})

        # 保存用户浏览数据
        redis_conn = get_redis_connection('history')
        # 管道
        pl = redis_conn.pipeline()
        user_id = request.user.id

        # 先去重
        pl.lrem('history_%s' % user_id, 0, sku_id)
        # 再存储
        pl.lpush('history_%s' % user_id, sku_id)
        # 最后截取
        pl.ltrim('history_%s' % user_id, 0, 4)
        # 执行管道
        pl.execute()

        # 响应结果
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})

    def get(self, request):
        """获取用户浏览记录"""
        # 获取Redis存储的sku_id列表信息
        redis_conn = get_redis_connection('history')
        sku_ids = redis_conn.lrange('history_%s' % request.user.id, 0, 4 )

        # 根据sku_ids列表数据，查询出商品sku信息
        skus = []
        for sku_id in sku_ids:
            sku = SKU.objects.get(id=sku_id)
            skus.append({
                'id': sku.id,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price
            })

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'skus': skus})


# 订单展示
# 订单展示
class OredrDisplayView(LoginRequiredMixin,View):
    def get(self,request):
        user = request.user
        ids = OrderInfo.objects.filter(user=user.id)

        order_list = []
        goods_list = []

        for order in ids:
            goods = OrderGoods.objects.filter(order=order.order_id)

            for good in goods:
                sku = SKU.objects.get(id=good.sku_id)
                if order.pay_method == 1:
                    pay_method = '货到付款'
                else:
                    pay_method = '支付宝'
                order_list.append({
                    'price':str(good.price),
                    'count':good.count,
                    'total_amount':str(good.price*good.count),
                    'name':good.sku.name,
                    'default_image_url':good.sku.default_image,
                })

                goods_list.append({
                    'details':order_list,
                    'create_time':good.create_time,
                    'order_id':good.order_id,
                    'freight':order.freight,
                    'status':order.status,
                    'total_amount': order.total_amount,
                    'pay_method':pay_method

                })
                paginator = Paginator(good.order_id, 2)
                # 获取当前页数据
                page = paginator.page(1)


            context={
                'page': goods_list,
                'page_num':1,

            }

            return render(request,'user_center_order.html',context)





